#ifndef AST_BASETYPE
#define AST_BASETYPE
#include <string>
#include "node.h"

namespace AST {

    /**
     * Tipo Base de Dados
     *
     * Estrutura representante de tipos básicos da linguagem e que são
     * utilizados durante as definições de variáveis ou funções, atribuindo
     * assim tipagem aos seus valores.
     *
     * @category AST
     * @package  AST
     */
    class Basetype : public Node {

    private:

        /**
         * Conteúdo Capturado pelo Token
         */
        std::string* _content;

        /**
         * Dimensões Utilizadas
         */
        unsigned int _dimensions;

        /**
         * Configura o Conteúdo Capturado pelo Token
         *
         * Armazena o identificador que representa o conteúdo capturado pelo
         * Token durante a leitura da entrada ao compilador. Este conteúdo
         * representa o tipo de dado que foi definido durante a escrita do
         * programa para aquela instrução.
         *
         * @param  std::string* Conteúdo Capturado pelo Token
         * @return Basetype*    Próprio Objeto para Encadeamento
         */
        Basetype* _setContent(std::string*);

    public:

        /**
         * Construtor
         *
         * Método responsável pela criação de uma instância da classe derivada
         * de nó de árvore abstrata de sintaxe que representa tipos de dados
         * definidos durante a execução. Recebe como parâmetro o tipo de dado
         * apresentado naquele ponto de código.
         *
         * @param std::string* Conteúdo Capturado pelo Token
         */
        Basetype(std::string*);

        /**
         * Apresenta o Conteúdo Capturado pelo Token
         *
         * O conteúdo definido como tipo de dado na linguagem é aquele definido
         * em tempo de construção do objeto e que pode ser capturado através
         * deste método.
         *
         * @return std::string Conteúdo Solicitado
         */
        std::string* getContent();

        /**
         * Configura a Quantidade de Dimensões
         *
         * Durante a declaração de uma variável no programa, esta pode estar
         * sendo declarada como vetorial. Sendo assim, precisamos adicionar a
         * quantidade de dimensões que este vetor está sendo declarado. Podemos
         * concluir que se a quantidade de dimensões é igual a zero, esta não
         * está sendo utilizada como vetor.
         *
         * @param  unsigned int Quantidade de Dimensões
         * @return Basetype* Próprio Objeto para Encadeamento
         */
        Basetype* setDimensions(unsigned int);

        /**
         * Captura de Quantidade de Dimensões
         *
         * A declaração de um tipo de variável pode ser configurada como
         * vetorial. Caso a quantidade de dimensões apresentadas seja igual a
         * zero, esta variável não está sendo utilizada como vetor; caso
         * contrário, o número apresentado apresenta a quantidade de dimensões
         * declaradas para o vetor.
         *
         * @return int Quantidade de Dimensões Configuradas
         */
        unsigned int getDimensions();

        /**
         * Inclusão de Dimensões na Tipagem
         *
         * Durante uma especificação, como a produção na gramática gera a
         * declaração vetorial de um tipo básico de forma que árvore com
         * profundidade, precisamos de um método que adicione uma quantidade
         * específica de elementos na altura da árvore gerada, caracterizando a
         * quantidade de dimensões especificadas para a tipagem. Caso seja
         * necessário remover dimensões, basta informar um parâmetro negativo.
         *
         * @param  int Quantidade de Dimensões para Inclusão
         * @return Basetype* Próprio Objeto para Encadeamento
         */
        Basetype* addDimensions(int);

        // Sobrescrita
        std::string toString(int);

    };

};

#endif

